using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Data;

namespace XBLib.BusinessObject
{
    public class BindableBusinessObject : BaseBusinessObject
    {
        protected Dictionary<PropertyInfo, List<ColumnAttributes>> _structureInfo;
        public BindableBusinessObject()
        {
            _structureInfo = null;
        }

        private List<ColumnAttributes> convertToListAttribute(Attribute[] attributes)
        {
            List<ColumnAttributes> results = new List<ColumnAttributes>();
            foreach (Attribute attribute in attributes)
            {
                results.Add((ColumnAttributes)attribute);
            }
            return results;
        }

        protected void getStructureInfo()
        {
            if (_structureInfo == null)
            {
                _structureInfo = new Dictionary<PropertyInfo, List<ColumnAttributes>>();
                Type type = this.GetType();

                PropertyInfo[] properties = type.GetProperties();
                PropertyInfo property;
                Attribute[] attributeArray;
                List<ColumnAttributes> attributes;
                try
                {
                    for (int i = 0; i < properties.Length; i++)
                    {
                        property = properties[i];
                        attributeArray = Attribute.GetCustomAttributes(property, typeof(ColumnAttributes), false);
                        if (attributeArray != null || attributeArray.Length > 0)
                        {
                            attributes = convertToListAttribute(attributeArray);
                            _structureInfo.Add(property, attributes);
                        }
                    }
                }
                catch (Exception) { throw; }
            }
        }

        private void setPropertyValue(PropertyInfo property, object value)
        {
            try
            {
                switch (property.PropertyType.Name)
                {
                    case "Enum":
                        property.SetValue(this, Enum.Parse(property.PropertyType, Convert.ToString(value)), null);
                        break;
                    case "String":
                        property.SetValue(this, Convert.ToString(value), null);
                        break;
                    case "Single":
                        property.SetValue(this, Convert.ToSingle(value), null);
                        break;
                    case "Double":
                        property.SetValue(this, Convert.ToSingle(value), null);
                        break;
                    case "Int32":
                        property.SetValue(this, Convert.ToInt32(value), null);
                        break;
                    //case "DateTime":
                    //    if (row[attribute.ColumnName].ToString().Trim().Length == 6)
                    //        property.SetValue(this, DateTime.ParseExact(row[attribute.ColumnName].ToString().Trim() + "01", "yyyyMMdd", null), null);
                    //    else if (row[attribute.ColumnName].ToString().Trim().Length == 8)
                    //        property.SetValue(this, DateTime.ParseExact(row[attribute.ColumnName].ToString().Trim(), "yyyyMMdd", null),null);
                    //    else property.SetValue(this, row[attribute.ColumnName], null);
                    default:
                        property.SetValue(this, value, null);
                        break;
                }
            }
            catch (Exception ex)
            { }
        }

        public void GetData(DataRow row)
        {
            getStructureInfo();
            PropertyInfo property;
            List<ColumnAttributes> attributes;
            try
            {
                foreach (KeyValuePair<PropertyInfo, List<ColumnAttributes>> keyValue in _structureInfo)
                {
                    property = keyValue.Key;
                    attributes = keyValue.Value;
                    foreach (ColumnAttributes attribute in attributes)
                    {
                        if (row.Table.Columns.Contains(attribute.ColumnName) && !row.IsNull(attribute.ColumnName))
                        {
                            if (property.PropertyType.FullName.Equals("System.DateTime"))
                                if (row[attribute.ColumnName].ToString().Trim().Length == 6)
                                    setPropertyValue(property, DateTime.ParseExact(row[attribute.ColumnName].ToString().Trim() + "01", "yyyyMMdd", null));
                                else if (row[attribute.ColumnName].ToString().Trim().Length == 8)
                                    setPropertyValue(property, DateTime.ParseExact(row[attribute.ColumnName].ToString().Trim(), "yyyyMMdd", null));
                                else
                                    setPropertyValue(property, row[attribute.ColumnName]);
                            else
                                if (property.PropertyType.FullName.Equals("System.String"))
                                    setPropertyValue(property, row[attribute.ColumnName].ToString());
                                else
                                    setPropertyValue(property, row[attribute.ColumnName]);
                            break;

                        }
                    }
                }
            }
            catch (Exception) { throw; }
        }

        public void GetData(IDataReader reader)
        {
            getStructureInfo();
            PropertyInfo property;
            List<ColumnAttributes> attributes;
            try
            {
                foreach (KeyValuePair<PropertyInfo, List<ColumnAttributes>> keyValue in _structureInfo)
                {
                    property = keyValue.Key;
                    attributes = keyValue.Value;
                    foreach (ColumnAttributes attribute in attributes)
                    {
                        if (reader[attribute.ColumnName] != null && reader[attribute.ColumnName] != DBNull.Value)
                        {
                            setPropertyValue(property, reader[attribute.ColumnName]);
                            //property.SetValue(this, reader[attribute.ColumnName], null);
                            break;
                        }
                    }
                }
            }
            catch (Exception) { throw; }
        }
    }
}
